<!DOCTYPE html><html><head><meta charset="utf-8"><style>html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }

body{
  color:#444;
  font-family:Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman',
              "Hiragino Sans GB", "STXihei", "微软雅黑", serif;
  font-size:12px;
  line-height:1.5em;
  background:#fefefe;
  width: 45em;
  margin: 10px auto;
  padding: 1em;
  outline: 1300px solid #FAFAFA;
}

a{ color: #0645ad; text-decoration:none;}
a:visited{ color: #0b0080; }
a:hover{ color: #06e; }
a:active{ color:#faa700; }
a:focus{ outline: thin dotted; }
a:hover, a:active{ outline: 0; }

span.backtick {
  border:1px solid #EAEAEA;
  border-radius:3px;
  background:#F8F8F8;
  padding:0 3px 0 3px;
}

::-moz-selection{background:rgba(255,255,0,0.3);color:#000}
::selection{background:rgba(255,255,0,0.3);color:#000}

a::-moz-selection{background:rgba(255,255,0,0.3);color:#0645ad}
a::selection{background:rgba(255,255,0,0.3);color:#0645ad}

p{
margin:1em 0;
}

img{
max-width:100%;
}

h1,h2,h3,h4,h5,h6{
font-weight:normal;
color:#111;
line-height:1em;
}
h4,h5,h6{ font-weight: bold; }
h1{ font-size:2.5em; }
h2{ font-size:2em; border-bottom:1px solid silver; padding-bottom: 5px; }
h3{ font-size:1.5em; }
h4{ font-size:1.2em; }
h5{ font-size:1em; }
h6{ font-size:0.9em; }

blockquote{
color:#666666;
margin:0;
padding-left: 3em;
border-left: 0.5em #EEE solid;
}
hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; }


pre , code, kbd, samp { 
  color: #000; 
  font-family: monospace; 
  font-size: 0.88em; 
  border-radius:3px;
  background-color: #F8F8F8;
  border: 1px solid #CCC; 
}
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; padding: 5px 12px;}
pre code { border: 0px !important; padding: 0;}
code { padding: 0 3px 0 3px; }

b, strong { font-weight: bold; }

dfn { font-style: italic; }

ins { background: #ff9; color: #000; text-decoration: none; }

mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }

sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }

ul, ol { margin: 1em 0; padding: 0 0 0 2em; }
li p:last-child { margin:0 }
dd { margin: 0 0 0 2em; }

img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }

table { border-collapse: collapse; border-spacing: 0; }
td { vertical-align: top; }

@media only screen and (min-width: 480px) {
body{font-size:14px;}
}

@media only screen and (min-width: 768px) {
body{font-size:16px;}
}

@media print {
  * { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; }
  body{font-size:12pt; max-width:100%; outline:none;}
  a, a:visited { text-decoration: underline; }
  hr { height: 1px; border:0; border-bottom:1px solid black; }
  a[href]:after { content: " (" attr(href) ")"; }
  abbr[title]:after { content: " (" attr(title) ")"; }
  .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
  pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; }
  tr, img { page-break-inside: avoid; }
  img { max-width: 100% !important; }
  @page :left { margin: 15mm 20mm 15mm 10mm; }
  @page :right { margin: 15mm 10mm 15mm 20mm; }
  p, h2, h3 { orphans: 3; widows: 3; }
  h2, h3 { page-break-after: avoid; }
}
</style></head><body><h1 id="1-restful-api">1. Restful API</h1>

<p>A RESTful API is a (usually Web) service that exposes its functionality as Resources. REST maps greatly with HTTP verbs, which allow basic CRUD operations along with a few other practical things such as the recent PATCH verb, and HEAD, to get information about the resource.</p>

<p>Advantages include a clean and stable API. The verbs are basically always the same, and when using emerging standards such as HAL, a REST api basically becomes self-describing. Any resources points to itself and related resources, along with possible actions against it. Since the HTTP transport has all the facilities necessary for authentication, paging, localization and content negociation, it is easy for anyone that knows the Web to get it. It also makes payload lighter.</p>

<p>Some disadvantages are also there. There is no standard way of describing the API (such as a WSDL file for SOAP) and clients need to know about the resources and what properties they contain.</p>

<h1 id="2-json-jsonp-and-xml">2. JSON, JSONP and XML</h1>

<ul>
<li>JSON is a markup language that is very similar (but not 100% compatible) to JavaScript's Object Notation.</li>
<li>JSONP is a way to get JSON over HTTP for easier cross domain requests. It is basically JSON wrapper inside a JavaScript callback.</li>
<li>XML is a markup language based on SGML, but it is much stricter. It includes many features for extensibility such as namespaces.</li>
</ul>

<p>I have also worked with YAML, which is an indentation based markup language, mostly used by Python and Ruby frameworks.</p>

<h1 id="3-mvc">3. MVC</h1>

<p>MVC stands for Model View Controller. Controllers receive requests from the UI (a GUI framework or a Web browser), use the model to query or modify data and then return control to the UI. In the case of a browser, the interaction is mostly stateless, while in Desktop application, the view will sometimes use the controller to execute commands or get data.</p>

<p>I've worked with Rails, Django a tiny bit and extensively with asp.NET MVC (1 through 4).</p>

<h1 id="4-database-schema">4. Database schema</h1>

<p>Assuming it's a "blog" style application.</p>

<p><strong>Table "Posts":</strong></p>

<ul>
<li>Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1)</li>
<li>Header NVARCHAR(MAX) NOT NULL</li>
<li>Body NVARCHAR(MAX) NOT NULL</li>
<li>SourceName NVARCHAR(MAX) NOT NULL</li>
<li>SourceUrl NVARCHAR(MAX) NOT NULL</li>
<li>Timestamp DATETIME NOT NULL</li>
<li>AuthorId INT FOREIGN KEY REFERENCES Authors (Id)</li>
</ul>

<p><strong>Table "Authors":</strong></p>

<ul>
<li>Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1)</li>
<li>Name NVARCHAR(MAX) NOT NULL</li>
</ul>

<p><strong>Table "Tags":</strong></p>

<ul>
<li>Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1)</li>
<li>Tag NVARCHAR(250) NOT NULL</li>
</ul>

<p><strong>Table "PostTags":</strong></p>

<ul>
<li>PostId INT NOT NULL FOREIGN KEY REFERENCES Posts (Id)</li>
<li>TagId INT NOT NULL FOREIGN KEY REFERENCES Tags (Id)</li>
<li>PRIMARY KEY (PostID, TagId)</li>
</ul>

<p>I would probably create a REST api because it already has support for caching and provides a great interoperable transport (HTTP) which can be used by server apps, mobile applications or desktop applications.</p>

<p><strong>Resource "/posts"</strong></p>

<ul>
<li>Lists the latest 10 posts (use Range header or whichever one is appropriate for paging if necessary)</li>
<li>Each post resource points to its tags</li>
<li>Query string parameters could be used to filter according to timestamp, author or keywords</li>
</ul>

<p><strong>Sub resource "/posts/{id}/tags"</strong></p>

<ul>
<li>Gets the tags for a specific post.</li>
</ul>

<p>This would allow an MVC application to easily get a post and its tags. A mobile web site could also directly query the API for maximum efficiency.</p>

<p>I don't think performance would be an issue with views that join the posts, authors and tags table. Any decent SQL server can handle this load easily.</p>

<p>If there are performance problems, there are multiple ways to enhance them. A read-only database could be created on the side, which would have only one table with all the information flattened (i.e. AuthorId, AuthorName, Tags (comma separated list or similar)). There are also indexing/searching services such as Solr or Elastic Search which can be set up to regularly update their index from the actual data and can be greatly optimized for specific queries and ordering. I've personally used Solr to search in a table of 1,500,000 entries, and it usually took around 10ms.</p>

<p>I actually cannot tell what mapping and indexing refer to in the question. If indexing means Database indices, I'd probably use a profiling tool to figure out which queries require optimization and optimize them specifically.</p>

<h1 id="5-automatic-keyword-generation">5. Automatic keyword generation</h1>

<p>A basic implementation would go through all posts, split them all into words. Remove the small, recurrent words from a dictionary of the language of the posts (e.g. "the", "a", "in"). Remove most common verbs as well.</p>

<p>Then, count each word and assign them a score according to their global frequency and frequency within a post. Assign more points for words inside a header. Pick the 5~10 highest scoring ones.</p>

<h1 id="6-new-service">6. New service</h1>

<h2 id="top-news-entries">Top news entries</h2>

<p>Using any popularity algorithm (some use upvotes or likes, some page views, some clicks on links), I'd have an column on the entries that contained a number that we could sort on.</p>

<h2 id="popular-tags">Popular tags</h2>

<p>Regularly update the tag's popularity according to the popularity of all the posts within that tag. Calculate this index every few hours to keep it updated, and store values with timestamps so we can see trends over longer periods of time.</p>

<h2 id="stories-for-a-specified-day">Stories for a specified day</h2>

<p>Issue a SELECT * FROM Posts WHERE Timestamp BETWEEN {beginning-of-day-specified} AND {end-of-day-specified}</p>

<h2 id="individual-entry-details">Individual entry details</h2>

<p>Select all the data from the table.</p>

<h2 id="search">Search</h2>

<p>I would probably implement a full-text search indexer such as Solr or Elastic Search. These are purposely built for this and can be tweaked according to languages, stop word dictionaries and a lot of other options for searching.</p>

<h2 id="future-proofing">Future proofing</h2>

<p>I think with a read-only database, Solr and a few indices, the data will be easily scaled for future needs.</p>

<h1 id="7-sql-vs-nosql">7. SQL vs. noSQL</h1>

<p>SQL is incredibly powerful for relational data with rigorous a schema. noSQL stores are more geared towards simple key/value pairs without schemas.</p>

<p>In a case where most of the data access will be done directly by key and there is few related data bunched together, a noSQL store would be very efficient.</p>

<p>In cases where data integrity is of the utmost importance, a regular SQL database would be more approriate.</p>

<p>A noSQL store can also be used as a caching store, over an existing SQL database. Considering some noSQL stores can be handled in memory, it can make for an extremely fast caching mechanism.</p>

<h1 id="8-uri-shortening-service">8. URI shortening service</h1>

<p>The Unique ID would probably be a "sequential" string containing as many different characters as possible for each character in the final string. i.e. [a-zA-Z0-9]. This would give maximum range for the shortest numbers of characters.</p>

<pre><code>http://sho.rt/a
http://sho.rt/aaaaab03 // which is now huge!
</code></pre>

<p>I would probably use a noSQL store (such as Redis) for this. Each shortened URL id would be a key, containing the actual URL as well as any other related data, such as number of redirects.</p>

<p>I'd use 301 redirects so browsers and spiders wouldn't think this page has actual content.</p>

<p>For analytics, I'd probably create another Redis store to put relevant data, such as referrers, time of days where links are visited and so on. With proper queries, it would be easy to build trend data.</p>

<h1 id="9-poker-feed">9. Poker Feed</h1>

<p>I'm not too sure what exactly I'm supposed to do. I did a bit of optimization in the original feed and then "translated" most important things and one title.</p>

<ul>
<li><a href="/static/interviews/thomson-reuters-2/feed.en.json">feed.en.json</a></li>
<li><a href="/static/interviews/thomson-reuters-2/feed.fr.json">feed.fr.json</a></li>
</ul>

<p>All static values are now "enum" values from the Configuration object at the top, which also contains lookup values for displaying in the language of the feed. Sorting can be done either on the enum name, or a quick dictionary lookup can be made to sort.</p>

<h1 id="10-stakeholder-email">10. Stakeholder email</h1>

<p>I honestly do not know where to begin with this. Working with slightly abstract concepts and discussing solutions is one thing, but answering to a bunch of mumbo-jumbo buzzwords in a day and a half is not a very smart way of going forward with projects. If I were confronted with this problem in real life, I would schedule a phone call with both Tom and John to figure out what exactly is happening, and why we want to re-create the wheel from scratch. It seems to me like what they want is a custom OS that can also run all kinds of apps (Windows, Linux, Android, iPhone) which is a silly, silly thing.</p>

<p>All these requests for estimates and 3-week early prototype are incredibly short. Estimates on the unknown give no real data and are basically useless.</p>

<p>I cannot write anything against this, as it would be incredibly abstract, full of conjecture and pretty boring to boot.</p>
</body></html>